import Vue from 'vue'

import Cookies from 'js-cookie'

import Element from 'element-ui'
import './assets/styles/element-variables.scss'

import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import App from './App'
import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'
// require('./mock') // Mock数据，如需关闭请注释此行
import './assets/icons' // icon
import './permission' // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
// 分页组件
import Pagination from "@/components/Pagination";
// 自定义表格工具组件
import RightToolbar from "@/components/RightToolbar"
// 富文本组件
import Editor from "@/components/Editor"
// 文件上传组件
import FileUpload from "@/components/FileUpload"
// 图片上传组件
import ImageUpload from "@/components/ImageUpload"
// 图片预览组件
import ImagePreview from "@/components/ImagePreview"
// 字典标签组件
import DictTag from '@/components/DictTag'
// 头部标签组件
import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
// 高德地图配置
import VueAMap from 'vue-amap' // 引入插件


// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree

// 全局组件挂载
Vue.component('DictTag', DictTag)
Vue.component('Pagination', Pagination)
Vue.component('RightToolbar', RightToolbar)
Vue.component('Editor', Editor)
Vue.component('FileUpload', FileUpload)
Vue.component('ImageUpload', ImageUpload)
Vue.component('ImagePreview', ImagePreview)

Vue.use(directive)
Vue.use(plugins)
Vue.use(VueMeta)

// 高德地图配置
Vue.use(VueAMap)

VueAMap.initAMapApiLoader({
  key: 'a3e080828d974d44b6c6eae6b888b023',
  plugin: [
    'AMap.Geocoder',
    'AMap.PlaceSearch',
    'AMap.Geolocation',
    'AMap.CitySearch',
    'AMap.Scale',
    'AMap.OverView',
    'AMap.ToolBar',
    'AMap.MapType',
    'AMap.PolyEditor',
    'AMap.CircleEditor'
  ],
  uiVersion: '1.0.11',
  v: '1.4.15'
})

// 安全密钥配置
window._AMapSecurityConfig = {
  securityJsCode: '6451f029acefcc8a0ff21363e5b52330'
}

DictData.install()

/**
 * If you don't want to use mock-server
 * you want to use Js for mock api
 * you can execute: mockXHR()
 *
 * Currently MockJs will be used in the production environment,
 * please remove it before going online! ! !
 */

Vue.use(Element, {
  size: Cookies.get('size') || 'medium' // set element-ui default size
})

Vue.config.productionTip = false

/**
 * 从原始 URL 字符串中直接提取参数值，避免浏览器自动解码 + 号
 * 关键：直接从 href 中提取，不经过浏览器解码
 */
function getRawQueryString() {
  const href = window.location.href;
  let queryString = '';

  // 查找 ? 号的位置
  const questionMarkIndex = href.indexOf('?');
  if (questionMarkIndex === -1) {
    // 如果 search 中没有，尝试从 hash 中获取（参数在 # 之后）
    const hashMatch = href.match(/#[^#]*\?([^#]*)/);
    if (hashMatch) {
      queryString = hashMatch[1];
    }
    return queryString;
  }

  // 查找 # 号的位置（查询字符串在 # 之前）
  const hashIndex = href.indexOf('#', questionMarkIndex);

  if (hashIndex === -1) {
    // 没有 # 号，查询字符串到 URL 末尾
    queryString = href.substring(questionMarkIndex + 1);
  } else {
    // 有 # 号，查询字符串在 ? 和 # 之间
    queryString = href.substring(questionMarkIndex + 1, hashIndex);
  }

  // 如果 search 中没有，尝试从 hash 中获取（参数在 # 之后）
  if (!queryString) {
    const hashMatch = href.match(/#[^#]*\?([^#]*)/);
    if (hashMatch) {
      queryString = hashMatch[1];
    }
  }

  return queryString;
}

/**
 * 手动解析查询字符串，正确处理 + 号编码问题
 * 关键：在解码之前，先将所有 + 号替换为 %2B，防止被解码为空格
 */
function parseQueryString(queryString) {
  const params = {};
  if (!queryString) return params;

  console.log('原始查询字符串:', queryString);

  // 先分割参数
  const pairs = queryString.split('&');

  pairs.forEach(pair => {
    const equalIndex = pair.indexOf('=');
    if (equalIndex === -1) return;

    const key = pair.substring(0, equalIndex);
    let value = pair.substring(equalIndex + 1);

    console.log(`解析参数 ${key}: 原始值长度 = ${value.length}, 包含 + 号数量 = ${(value.match(/\+/g) || []).length}`);

    if (key && value !== undefined) {
      try {
        // 关键步骤：在解码之前，先将所有 + 号替换为 %2B（+ 的 URL 编码）
        // URL 规范中，+ 号在查询字符串中可以表示空格，但这里的参数值（加密数据）中的 + 号
        // 应该被保留为 + 号，而不是被解码为空格
        // 所以我们将所有 + 号先替换为 %2B，然后再解码，这样 + 号就会被保留
        let protectedValue = value.replace(/\+/g, '%2B');

        // 然后进行 URL 解码
        // 注意：如果值中还有其他编码（如 %20 表示空格），这里也会正确解码
        const decodedValue = decodeURIComponent(protectedValue);

        console.log(`解析参数 ${key}: 解码后长度 = ${decodedValue.length}, 包含空格数量 = ${(decodedValue.match(/ /g) || []).length}`);
        console.log(`解析参数 ${key}: 解码后前100个字符 = "${decodedValue.substring(0, 100)}"`);

        params[key] = decodedValue;
      } catch (e) {
        // 如果解码失败，可能是格式问题
        console.warn(`参数 ${key} 解码失败:`, e, '原始值前100字符:', value.substring(0, 100));
        // 如果解码失败，直接使用原始值（但需要将可能的空格还原为 +）
        // 不过这种情况应该是参数本身有问题
        params[key] = value;
      }
    }
  });

  return params;
}

/**
 * 从 URL 中提取登录参数
 * 支持两种方式：
 * 1. 参数在 # 之前：?data=xxx&encryption=xxx&systemCode=xxx
 * 2. 参数在 # 之后：/#/path?data=xxx&encryption=xxx&systemCode=xxx
 */
function getQueryParams() {
  // 从原始 URL 获取查询字符串，避免浏览器自动解码
  const rawQueryString = getRawQueryString();
  console.log('从原始 URL 提取的查询字符串:', rawQueryString);

  const parsedParams = parseQueryString(rawQueryString);

  // 只返回需要的参数
  const params = {};
  if (parsedParams.data || parsedParams.encryption || parsedParams.systemCode) {
    params.data = parsedParams.data;
    params.encryption = parsedParams.encryption;
    params.systemCode = parsedParams.systemCode;
  }

  return params;
}

/**
 * 修复参数值中被错误转换为空格的 + 号
 * 如果参数是加密数据（长字符串），其中的空格很可能是被错误转换的 + 号
 */
function fixEncodedParams(params) {
  const fixedParams = { ...params };

  // 对于加密参数（data 和 encryption），如果包含空格，很可能是 + 号被错误转换
  // 将这些空格还原为 + 号
  if (fixedParams.data && typeof fixedParams.data === 'string') {
    // 检查原始 URL 中是否有 + 号（如果已经被转换，window.location.href 中可能没有）
    // 对于加密数据，空格应该被还原为 + 号
    fixedParams.data = fixedParams.data.replace(/ /g, '+');
  }

  if (fixedParams.encryption && typeof fixedParams.encryption === 'string') {
    fixedParams.encryption = fixedParams.encryption.replace(/ /g, '+');
  }

  return fixedParams;
}

/**
 * 处理首次访问，提取并存储登录参数，清除 URL 中的参数
 */
(function handleFirstVisit() {
  const { data, encryption, systemCode } = getQueryParams();
  console.log('原始 URL:', window.location.href);
  console.log('解析后的参数（修复前）:', { data, encryption, systemCode });
  console.log("最新版本------------------------");
  // 修复可能被错误转换为空格的 + 号
  const fixedParams = fixEncodedParams({ data, encryption, systemCode });
  console.log('修复后的参数:', fixedParams);

  if (fixedParams.data && fixedParams.encryption && fixedParams.systemCode) {
    // ✅ 保存参数到 localStorage
    localStorage.setItem('byznjcParams', JSON.stringify(fixedParams));

    // ✅ 清除 URL 中的参数，只保留干净的路径
    // hash 模式：清除 search 和 hash 中的参数
    let cleanUrl = window.location.origin + window.location.pathname;

    // 如果 hash 中有路径（如 #/path），保留路径部分，去掉参数
    const hash = window.location.hash;
    if (hash && hash.includes('#')) {
      const hashPathMatch = hash.match(/#([^?]*)/);
      if (hashPathMatch && hashPathMatch[1]) {
        cleanUrl += '#' + hashPathMatch[1];
      } else {
        cleanUrl += '#/';
      }
    } else {
      cleanUrl += '#/';
    }

    window.history.replaceState({}, document.title, cleanUrl);
  }
})()

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})
